`include "defines.v"
module ctrl(
	input wire rst,
	input wire pause_from_id,
	input wire pause_from_ex,
	//异常相关
	input wire[31:0] cp0_epc_i, //epc寄存器最新值
	input wire[31:0] exception_type_i, //异常类型
	output reg[31:0] exception_addr_o, //异常处理程序入口地址
	output reg exception_o, //是否发生异常
	output reg[5:0] pause
	
);
	//PAUSE[5:0]分别对应pc,取指，译码，执行，访存，写回阶段是否暂停
	always@(*)
		if(rst == `RstEnable)
		begin
			pause = 6'b000000;
			exception_addr_o = `ZeroWord;
			exception_o = `Exception_No_Happen;
		end
		else if(exception_type_i != `ZeroWord)
		begin
			pause = 6'b000000;
			exception_o = `Exception_Happen;
			case(exception_type_i)
				32'h0000_0001: //中断
					exception_addr_o = 32'h0000_0020;
				32'h0000_0008: //系统调用
					exception_addr_o = 32'h0000_0040;
				32'h0000_000a: //无效指令
					exception_addr_o = 32'h0000_0040;
				32'h0000_000d: //自陷指令
					exception_addr_o = 32'h0000_0040;
				32'h0000_000c: //溢出
					exception_addr_o = 32'h0000_0040;
				32'h0000_000e: //异常返回
					exception_addr_o = cp0_epc_i;
				default
					exception_addr_o = `ZeroWord;
			endcase
		end
		else if(pause_from_ex == `PAUSE)
		begin
			pause = 6'b001111;
			exception_addr_o = `ZeroWord;
			exception_o = `Exception_No_Happen;
		end
		else if(pause_from_id == `PAUSE)
		begin
			pause = 6'b000111;
			exception_addr_o = `ZeroWord;
			exception_o = `Exception_No_Happen;
		end
		else
		begin
			pause = 6'b000000;
			exception_addr_o = `ZeroWord;
			exception_o = `Exception_No_Happen;
		end
endmodule
